<?php

namespace Admin\Controller;
use Zend\Form\Form;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Admin\Service\AdminUser as AdminUserServive;
use User\Options\UserControllerOptionsInterface;
use User\Mapper\HydratorInterface as Hydrator;
//use User\Service\User as UserService;

class UserController extends AbstractActionController
{
    const ROUTE_CREATE_USER     = 'admin/user/create';
    const ROUTE_LOGIN           = 'admin/user/login';
    
    const ROUTE_ADMIN_USER      = 'admin/user';

    const CONTROLLER_NAME       = 'Admin\Controller\UserController';

    /**
     * @var UserService
     */
    protected $userService;
    protected $createUserForm;
    protected $loginForm;
    protected $formHydrator;

    /**
     * @todo Make this dynamic / translation-friendly
     * @var string
     */
    protected $failedLoginMessage = 'Authentication failed. Please try again.';
    protected $options;

    public function indexAction()
    {
        $adminService = $this->getUserService();

        $userMapper = $adminService->getUserMapper();
        $users = $userMapper->fetchPaginator((int)$this->params()->fromQuery('page', 1));
        return new ViewModel(array(
            'users' => $users,
            'paginator' => $users
        ));
    }
    /*
     * Authenticate admin user
     */
    public function authenticateAction()
    {
        if ($this->AdminAuthentication()->hasIdentity()) {
            return $this->redirect()->toRoute($this->getOptions()->getLoginRedirectAdminRoute());
        }
        $adapter = $this->AdminAuthentication()->getAuthAdapter();
        $redirect = $this->params()->fromPost('redirect', $this->params()->fromQuery('redirect', false));
        $result = $adapter->prepareForAuthentication($this->getRequest());

        // Return early if an adapter returned a response
        if ($result instanceof Response) {
            return $result;
        }
        $auth = $this->AdminAuthentication()->getAuthService()->authenticate($adapter);

        if (!$auth->isValid())
        {
            $this->flashMessenger()->setNamespace('user-login-form')->addMessage($this->failedLoginMessage);
            $adapter->resetAdapters();
            return $this->redirect()->toUrl(
                $this->url()->fromRoute(static::ROUTE_LOGIN) .
                ($redirect ? '?redirect='. rawurlencode($redirect) : '')
            );
        }

        if ($this->getOptions()->getUseRedirectParameterIfPresent() && $redirect) {
            return $this->redirect()->toRoute($redirect);
        }

        $route = $this->getOptions()->getLoginRedirectAdminRoute();

        if (is_callable($route)) {
            $route = $route($this->AdminAuthentication()->getIdentity());
            //$route = $route($auth->getIndentity());
        }

        return $this->redirect()->toRoute($route);
    }
    
    public function loginAction()
    {
        $this->layout('layout/layout');
        if ($this->AdminAuthentication()->hasIdentity()) {
            return $this->redirect()->toRoute($this->getOptions()->getLoginRedirectAdminRoute());
        }
        
        $request = $this->getRequest();
        $form = $this->getLoginForm();

        if (!$request->isPost()) {
            return array(
                'form' => $form,
                'redirect'  => null,
                'enableRegistration' => $this->getOptions()->getEnableRegistration(),
            );
        }
        
        $post = $this->getRequest()->getPost();//prg;

        if (!$request->isPost()) {
            return array(
                'form' => $form,
                'redirect'  => null,
                'enableRegistration' => $this->getOptions()->getEnableRegistration(),
            );
        }

        $form->setData($post);

        if (!$form->isValid()) {
            /*return array(
                'form' => $form,
                'redirect'  => $redirect,
                'enableRegistration' => $this->getOptions()->getEnableRegistration(),
            );*/
            $this->flashMessenger()->setNamespace('user-login-form')->addMessage($this->failedLoginMessage);
            return $this->redirect()->toUrl($this->url()->fromRoute(static::ROUTE_LOGIN).($redirect ? '?redirect='. rawurlencode($redirect) : ''));
        }

        // clear adapters
        $this->AdminAuthentication()->getAuthAdapter()->resetAdapters();
        $this->AdminAuthentication()->getAuthService()->clearIdentity();
        
        return $this->forward()->dispatch(static::CONTROLLER_NAME, array('action' => 'authenticate'));
    }
    
    public function lockScreenAction()
    {
        $this->layout('layout/layout');
        $viewModel = new ViewModel();
        return $viewModel;
    }
    
    public function logoutAction()
    {
        $this->AdminAuthentication()->getAuthAdapter()->resetAdapters();
        $this->AdminAuthentication()->getAuthAdapter()->logoutAdapters();
        $this->AdminAuthentication()->getAuthService()->clearIdentity();

        $redirect = $this->params()->fromPost('redirect', $this->params()->fromQuery('redirect', false));

        if ($this->getOptions()->getUseRedirectParameterIfPresent() && $redirect) {
            return $this->redirect()->toRoute($redirect);
        }

        return $this->redirect()->toRoute($this->getOptions()->getLogoutRedirectAdminRoute());
    }
    
    public function createAction()
    {
        $form = $this->getCreateUserForm();
        $request = $this->getRequest();
        $adminUserService = $this->getUserService();

        /*
        if ($this->getOptions()->getUseRedirectParameterIfPresent() && $request->getQuery()->get('redirect')) {
            $redirect = $request->getQuery()->get('redirect');
        } else {
            $redirect = false;
        }

        $redirectUrl = $this->url()->fromRoute(static::ROUTE_CREATE_USER)
            . ($redirect ? '?redirect=' . rawurlencode($redirect) : '');

        $prg = $this->prg($redirectUrl, true);

        if ($prg instanceof Response)
        {
            return $prg;
        } elseif ($prg === false)
        {
            return array(
                'form' => $form,
                'enableRegistration' => $this->getOptions()->getEnableRegistration(),
                'redirect' => $redirect,
            );
        }

        //$post = $prg;*/
        if($request->isPost()){
            $post = array_merge_recursive(
                $this->getRequest()->getPost()->toArray(),
                $this->getRequest()->getFiles()->toArray()
            );
            $user = $adminUserService->createUser((array)$post);
            $redirect = null;//isset($prg['redirect']) ? $prg['redirect'] : null;

            if (!$user)
            {
                return array(
                    'form' => $form,
                    'enableRegistration' => $this->getOptions()->getEnableRegistration(),
                    'redirect' => $redirect,
                );
            }
            //var_dump($user);
            return $this->redirect()->toUrl($this->url()->fromRoute(static::ROUTE_ADMIN_USER) . ($redirect ? '?redirect='. rawurlencode($redirect) : ''));
        }
        return array(
            'form' => $form,
            'enableRegistration' => $this->getOptions()->getEnableRegistration(),
            'redirect' => null,
        );
    }

    public function updateAction()
    {
        $user_id = (int)$this->getEvent()->getRouteMatch()->getParam('id');
        if (!$user_id) {
            return $this->redirect()->toRoute('admin/user', array('action'=>'create'));
        }
        $adminService = $this->getUserService();

        $userMapper = $adminService->getUserMapper();

        $user = $userMapper->findById($user_id);
        $user->setPassword('');
        //$user->setRoleId($user->);
        $form = $this->getCreateUserForm();
        
        $form->setHydrator($this->getFormHydrator());
        $form->bind($user);
        //$form->get('role_id')->setValue($user->getRoleId());

        $request = $this->getRequest();
        $adminUserService = $this->getUserService();

        if ($this->getOptions()->getUseRedirectParameterIfPresent() && $request->getQuery()->get('redirect')) {
            $redirect = $request->getQuery()->get('redirect');
        } else {
            $redirect = false;
        }

        $redirectUrl = $this->url()->fromRoute(static::ROUTE_CREATE_USER)
            . ($redirect ? '?redirect=' . rawurlencode($redirect) : '') . 'update/' . $user_id;

        $prg = $this->prg($redirectUrl, true);

        if ($prg instanceof Response)
        {
            return $prg;
        } elseif ($prg === false)
        {
            return array(
                'form' => $form,
                'user_id' => $user_id,
                'enableRegistration' => $this->getOptions()->getEnableRegistration(),
                'redirect' => $redirect,
            );
        }

        $post = $prg;
        $user = $adminUserService->updateUser((array)$post);

        $redirect = null;//isset($prg['redirect']) ? $prg['redirect'] : null;

        if (!$user) {
            return array(
                'form' => $form,
                'user_id' => $user_id,
                'enableRegistration' => $this->getOptions()->getEnableRegistration(),
                'redirect' => $redirect,
            );
        }
        //var_dump($user);
        return $this->redirect()->toUrl($this->url()->fromRoute(static::ROUTE_ADMIN_USER) . ($redirect ? '?redirect='. rawurlencode($redirect) : ''));
    }

    public function deleteAction()
    {
        $user_id = (int)$this->getEvent()->getRouteMatch()->getParam('id');
        if (!$user_id) {
            return $this->redirect()->toRoute('admin/user', array('action'=>'index'));
        }
        $adminUserService = $this->getUserService();
        $adminUserService->deteleUser($user_id);
        return $this->redirect()->toUrl($this->url()->fromRoute(static::ROUTE_ADMIN_USER));
    }
    public function getUserService()
    {
        if(!$this->userService)
        {
            $this->setUserService($this->getServiceLocator()->get('admin_user_service'));
        }
        return $this->userService;
    }

    public function setUserService(AdminUserServive $userService)
    {
        $this->userService = $userService;
        return $this;
    }

    public function getCreateUserForm()
    {
        if (!$this->createUserForm) {
            $this->setCreateUserForm($this->getServiceLocator()->get('admin_create_form'));
        }
        return $this->createUserForm;
    }

    public function setCreateUserForm(Form $createUserForm)
    {
        $this->createUserForm = $createUserForm;
    }
    
    public function getUpdateUserForm()
    {
        if (!$this->createUserForm) {
            $this->setCreateUserForm($this->getServiceLocator()->get('admin_update_form'));
        }
        return $this->createUserForm;
    }

    public function setUpdateUserForm(Form $updateUserForm)
    {
        $this->createUserForm = $updateUserForm;
    }
    
     /*
     * get login form
     *
     */
    public function getLoginForm()
    {
        if(!$this->loginForm)
        {
            $this->setLoginForm($this->getServiceLocator()->get('user_login_form'));
        }
        return $this->loginForm;
    }

    /*
     * set login form
     */
    public function setLoginForm(Form $loginForm)
    {
        $this->loginForm = $loginForm;
        $fm = $this->flashMessenger()->setNamespace('user-login-form')->getMessages();
        if (isset($fm[0])) {
            $this->loginForm->setMessages(
                array('identity' => array($fm[0]))
            );
        }
        return $this;
    }
    
    /*
    * get Options
    * @return UserConrtollerOptionInterface
    */
    public function getOptions()
    {
        if(!$this->options instanceof UserControllerOptionsInterface)
        {
            $this->setOptions($this->getServiceLocator()->get('admin_module_options'));
        }
        return $this->options;
    }

    /**
     * set Options
     *
     * @param UserControllerOptionsInterface $options
     * @return UserController
     */
    public function setOptions(UserControllerOptionsInterface $options)
    {
        $this->options = $options;
        return $this;
    }

    /*
     * return form Hydrator
     */
    public function getFormHydrator()
    {
        if(!$this->formHydrator instanceof Hydrator)
        {
            $this->setFormHydrator($this->getServiceLocator()->get('user_hydrator'));
        }
        return $this->formHydrator;
    }

    public function setFormHydrator(Hydrator $formHydrator)
    {
        $this->formHydrator = $formHydrator;
        return $this;
    }
}

